﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Specialized;
using System.Collections;
using System.Data;
using System.Data.Common;
using System.Diagnostics;

namespace MySQL.Db
{
	class ResultSetColumnCollection : Dictionary<string, IResultSetColumn>
    {
		Collection<IResultSetColumn> indexedTypedColumns = new Collection<IResultSetColumn>();
/*
		internal void Populate(string csvColumns)
		{
			StringCollection columns = CsvParser.ParseLine(csvColumns);

			foreach (string col in columns)
				this.Add(col);
		}
*/
		internal void Populate(DbDataReader reader)
		{
			int colCount = reader.FieldCount;

			if (reader.Read())
			{
				for (int i = 0; i < colCount; i++)
				{
					IResultSetColumn c = this.AddColumn(reader, i);
					c.AddValueFromReader(reader);
				}
			}

			while (reader.Read())
			{
				for (int i = 0; i < colCount; i++)
					this.indexedTypedColumns[i].AddValueFromReader(reader);
			}
		}

		private IResultSetColumn AddColumn(DbDataReader reader, int ordinal)
		{
			IResultSetColumn c;

			string name = reader.GetName(ordinal);
			Type t = reader.GetFieldType(ordinal);

			// sequence below is carefully chosen. String type appears most freqently */
			if (t == typeof(string)) c = new ResultSetColumnString(name, ordinal);
			else if (t == typeof(decimal)) c = new ResultSetColumnDecimal(name, ordinal);
			else if (t == typeof(UInt32)) c = new ResultSetColumnUInt32(name, ordinal);
			else if (t == typeof(Int32)) c = new ResultSetColumnInt32(name, ordinal);
			else if (t == typeof(DateTime)) c = new ResultSetColumnDateTime(name, ordinal);
			else if (t == typeof(bool)) c = new ResultSetColumnBool(name, ordinal);
			else if (t == typeof(Int64)) c = new ResultSetColumnInt64(name, ordinal);
			else if (t == typeof(UInt64)) c = new ResultSetColumnUInt64(name, ordinal);
			else if (t == typeof(Int16)) c = new ResultSetColumnInt16(name, ordinal);
			else if (t == typeof(UInt16)) c = new ResultSetColumnUInt16(name, ordinal);
			else if (t == typeof(double)) c = new ResultSetColumnDouble(name, ordinal);
			else if (t == typeof(float)) c = new ResultSetColumnFloat(name, ordinal);
			else if (t == typeof(sbyte)) c = new ResultSetColumnSByte(name, ordinal);
			else if (t == typeof(byte)) c = new ResultSetColumnByte(name, ordinal);
			else if (t == typeof(char)) c = new ResultSetColumnChar(name, ordinal);
			else throw new Exception("Unknown type: " + t.Name);

			this[name] = c;
			indexedTypedColumns.Add(c);

			return c;
		}

		internal IResultSetColumn this[int index]
		{
			get { return this.indexedTypedColumns[index]; }
		}
    }
}
